/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
define(["require", "exports", "vscode-jsonrpc/events", "vscode-jsonrpc/is"], function (require, exports, events_1, Is) {
    'use strict';
    Object.defineProperty(exports, "__esModule", { value: true });
    var CancellationToken;
    (function (CancellationToken) {
        CancellationToken.None = Object.freeze({
            isCancellationRequested: false,
            onCancellationRequested: events_1.Event.None
        });
        CancellationToken.Cancelled = Object.freeze({
            isCancellationRequested: true,
            onCancellationRequested: events_1.Event.None
        });
        function is(value) {
            let candidate = value;
            return candidate && (candidate === CancellationToken.None
                || candidate === CancellationToken.Cancelled
                || (Is.boolean(candidate.isCancellationRequested) && !!candidate.onCancellationRequested));
        }
        CancellationToken.is = is;
    })(CancellationToken = exports.CancellationToken || (exports.CancellationToken = {}));
    const shortcutEvent = Object.freeze(function (callback, context) {
        let handle = setTimeout(callback.bind(context), 0);
        return { dispose() { clearTimeout(handle); } };
    });
    class MutableToken {
        constructor() {
            this._isCancelled = false;
        }
        cancel() {
            if (!this._isCancelled) {
                this._isCancelled = true;
                if (this._emitter) {
                    this._emitter.fire(undefined);
                    this._emitter = undefined;
                }
            }
        }
        get isCancellationRequested() {
            return this._isCancelled;
        }
        get onCancellationRequested() {
            if (this._isCancelled) {
                return shortcutEvent;
            }
            if (!this._emitter) {
                this._emitter = new events_1.Emitter();
            }
            return this._emitter.event;
        }
    }
    class CancellationTokenSource {
        get token() {
            if (!this._token) {
                // be lazy and create the token only when
                // actually needed
                this._token = new MutableToken();
            }
            return this._token;
        }
        cancel() {
            if (!this._token) {
                // save an object by returning the default
                // cancelled token when cancellation happens
                // before someone asks for the token
                this._token = CancellationToken.Cancelled;
            }
            else {
                this._token.cancel();
            }
        }
        dispose() {
            this.cancel();
        }
    }
    exports.CancellationTokenSource = CancellationTokenSource;
});
